package utils

import (
	"reflect"
	"strconv"
	"unsafe"
)

func IntToString(val int) string {
	return strconv.FormatInt(int64(val), 10)
}

func StringToInt(str string) int {
	if val, err := strconv.Atoi(str); err == nil {
		return val
	} else {
		return 0
	}
}

func Int8ToString(val int8) string {
	return strconv.FormatInt(int64(val), 10)
}

func StringToInt8(str string) int8 {
	if val, err := strconv.Atoi(str); err == nil {
		return int8(val)
	} else {
		return 0
	}
}

func Int16ToString(val int16) string {
	return strconv.FormatInt(int64(val), 10)
}

func StringToInt16(str string) int16 {
	if val, err := strconv.Atoi(str); err == nil {
		return int16(val)
	} else {
		return 0
	}
}

func Int32ToString(val int32) string {
	return strconv.FormatInt(int64(val), 10)
}

func StringToInt32(str string) int32 {
	if val, err := strconv.Atoi(str); err == nil {
		return int32(val)
	} else {
		return 0
	}
}

func Int64ToString(val int64) string {
	return strconv.FormatInt(int64(val), 10)
}

func StringToInt64(str string) int64 {
	if val, err := strconv.ParseInt(str, 10, 64); err == nil {
		return val
	} else {
		return 0
	}
}

func UintToString(val uint) string {
	return strconv.FormatUint(uint64(val), 10)
}

func StringToUint(str string) uint {
	if val, err := strconv.Atoi(str); err == nil {
		return uint(val)
	} else {
		return 0
	}
}

func Uint8ToString(val uint8) string {
	return strconv.FormatUint(uint64(val), 10)
}

func StringToUint8(str string) uint8 {
	if val, err := strconv.Atoi(str); err == nil {
		return uint8(val)
	} else {
		return 0
	}
}

func Uint16ToString(val uint16) string {
	return strconv.FormatUint(uint64(val), 10)
}

func StringToUint16(str string) uint16 {
	if val, err := strconv.Atoi(str); err == nil {
		return uint16(val)
	} else {
		return 0
	}
}

func Uint32ToString(val uint32) string {
	return strconv.FormatUint(uint64(val), 10)
}

func StringToUint32(str string) uint32 {
	if val, err := strconv.Atoi(str); err == nil {
		return uint32(val)
	} else {
		return 0
	}
}

func Uint64ToString(val uint64) string {
	return strconv.FormatUint(uint64(val), 10)
}

func StringToUint64(str string) uint64 {
	if val, err := strconv.ParseUint(str, 10, 64); err == nil {
		return val
	} else {
		return 0
	}
}

func Float32ToString(val float32) string {
	return strconv.FormatFloat(float64(val), 'f', -1, 32)
}

func StringToFloat32(str string) float32 {
	if val, err := strconv.ParseFloat(str, 10); err == nil {
		return float32(val)
	} else {
		return 0.0
	}
}

func Float64ToString(val float64) string {
	return strconv.FormatFloat(val, 'f', -1, 64)
}

func StringToFloat64(str string) float64 {
	if val, err := strconv.ParseFloat(str, 10); err == nil {
		return val
	} else {
		return 0.0
	}
}

func ByteToString(val []byte) string {
	return *(*string)(unsafe.Pointer(&val))
}

func StringToByte(val string) []byte {
	tmp1 := (*[2]uintptr)(unsafe.Pointer(&val))
	tmp2 := [3]uintptr{tmp1[0], tmp1[1], tmp1[1]}
	return *(*[]byte)(unsafe.Pointer(&tmp2))
}

func ToInt64(val interface{}) int64 {
	switch reflect.TypeOf(val).Kind() {
	case reflect.Int:
		return int64(val.(int))

	case reflect.Int8:
		return int64(val.(int8))

	case reflect.Int16:
		return int64(val.(int16))

	case reflect.Int32:
		return int64(val.(int32))

	case reflect.Int64:
		return val.(int64)

	case reflect.Uint:
		return int64(val.(uint))

	case reflect.Uint8:
		return int64(val.(uint8))

	case reflect.Uint16:
		return int64(val.(uint16))

	case reflect.Uint32:
		return int64(val.(uint32))

	case reflect.Uint64:
		return int64(val.(uint64))

	case reflect.String:
		return StringToInt64(val.(string))
	}
	return 0
}

func ToBool(val interface{}) bool {
	switch reflect.TypeOf(val).Kind() {
	case reflect.Int:
		if val.(int) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Int8:
		if val.(int8) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Int16:
		if val.(int16) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Int32:
		if val.(int32) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Int64:
		if val.(int64) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Uint:
		if val.(uint) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Uint8:
		if val.(uint8) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Uint16:
		if val.(uint16) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Uint32:
		if val.(uint32) > 0 {
			return true
		} else {
			return false
		}

	case reflect.Uint64:
		if val.(uint64) > 0 {
			return true
		} else {
			return false
		}

	case reflect.String:
		if len(val.(string)) > 0 {
			return true
		} else {
			return false
		}
	}
	return false
}
